<?php

namespace Wgx\Admin\Controller;

use Wgx\Admin\Com\AdminMenuRightsUtil;
use Wgx\Admin\Com\Crud\Crud;
use Wgx\Admin\Com\Crud\CrudField;
use Wgx\Admin\Com\Crud\CrudUserInterface;
use Wgx\Admin\Com\Crud\EditPageInput\InputCheckbox;
use Wgx\Admin\Com\Crud\EditPageInput\InputCheckboxGroup;
use Wgx\Admin\Com\Crud\EditPageInput\InputInput\InputText;
use Wgx\Admin\Com\Crud\EditPageInput\InputSelect;
use Wgx\Admin\Com\Crud\InvalidFieldValueException;
use Wgx\Admin\Com\Crud\ListPageSearchInput\InputInput\InputText as LpSearchInputText;
use Wgx\Admin\Com\Crud\ListPageSearchInput\InputSelect as LpSearchInputSelect;
use Wgx\Admin\Entity\AdminMenuEntity;
use Wgx\Admin\Entity\AdminToMenuEntity;
use PhpYes\Apps;
use PhpYes\Com\HttpException;
use PhpYes\Com\Router;
use PhpYes\Entity\BaseEntity;
use Wgx\PdoEx\QueryBuilder;

class AdminMenuController extends BaseController implements CrudUserInterface
{

    public function __construct()
    {
        /** @var Router $router */
        $router = \PhpYes\Apps::router();
        $func = $router->function;
        if ($func == 'getListDataWithLoginAuth') {
            $this->auth = self::AuthLogin;
        }
    }

    public function crud()
    {
        $crud = new Crud(AdminMenuEntity::getSingle(), $this);

        $crud->addField(new CrudField('id', 'id', 'id', CrudField::ShowInAll))
            ->addField(new CrudField('pid', '父菜单', '父菜单', CrudField::ShowInAll))
            ->addField(new CrudField('level', 'level', '', CrudField::ShowInListPage | CrudField::ShowInReadPage | CrudField::ShowInExport))
            ->addField(new CrudField('name', '名称', '菜单的名称', CrudField::ShowInAll))
            ->addField(new CrudField('path', '路径',
                <<<'PATHTIPS'
菜单由管理后台的url形成，为了进行权限的分配和管理。
在用户访问管理后台的一个url时，管理后台会放行有权限的访问，阻止没有权限的访问。
url中域名后面(指定了端口的话就是端口后面)至?前面的部分就叫做路径。
例如:
http://www.hostname.com?id=1 => / 就是路径(路径/省略了),
http://www.hostname.com/?id=1 => / 就是路径,
http://www.hostname.com/xxx?id=1 => /xxx 就是路径,
http://www.hostname.com:8080/xxx?id=1 => /xxx 就是路径
PATHTIPS
                , CrudField::ShowInAll))
            ->addField(new CrudField('rights', '权限', '可供分配的权限', CrudField::ShowInAll))
            ->addField(new CrudField('isInMenubar', '是否在菜单栏中',
                    '管理后台的左边是一个菜单栏，如果勾选此选项，本菜单将会展示在管理后台左边的菜单栏中；如果没有勾选此选项，本菜单将不会展示在管理后台左边的菜单栏中。',
                    CrudField::ShowInAll
                )
            )
            ->addField(new CrudField('priority', '顺序', '', CrudField::ShowInListPage))
            ->addField(new CrudField('icon', '图标',
                    <<<'ICONTIPS'
菜单如果展示在管理后台左边的菜单栏中，那么可以给菜单设置一个图标。
本管理后台目前支持的字体图标有: Font Awesome(5.3.1)。
此选项填写字体图标的 class。
例如:
Font Awesome 官网给出的图标的写法是 <i class="fas fa-info-circle"></i>, 那么选项应该填写 fas fa-info-circle
ICONTIPS
                    , CrudField::ShowInListPage | CrudField::ShowInReadPage | CrudField::ShowInEditPage
                )
            )
            ->addField(new CrudField('iconColor', '图标颜色',
                    <<<'ICONCOLORTIPS'
菜单如果展示图标的话，可以给图标指定一个颜色。
所有指定 color css 属性的方式都可以被支持。
例如:
red, #090, #009900, #009900aa, rgb(34, 12, 64, 0.6), rgba(34, 12, 64, 0.6), hsl(30, 100%, 50%, 0.6), hsla(30, 100%, 50%, 0.6), initial 等等
ICONCOLORTIPS
                    , CrudField::ShowInEditPage
                )
            )
            ->addField(new CrudField('defaultQuery', '默认url参数',
                    <<<'DEFAULTQUERYTIPS'
菜单如果展示在管理后台左边的菜单栏中，那么很可能还需要请求参数。
管理后台权限的分配和管理是基于 url的路径 的，所以菜单也就基于 url的路径 形成。但是真实访问用的 url 一般还有参数。此选项就用于指定默认url参数。
这里要求指定的url参数必须是 urlencode 后的参数，为了避免重复 urlencode, 后端不会进行 urlencode。
另外，这里指定url参数时不需要?,
例如:
hello=world, x1=y1&x2=y2, key=val&refer=https%3A%2F%2Fwww.baidu.com
DEFAULTQUERYTIPS
                    , CrudField::ShowInAll
                )
            );

        $rights = AdminMenuRightsUtil::getSingleObj()->getCurrentRights();
        if ($rights && ($rights & (AdminToMenuEntity::RightRead | AdminToMenuEntity::RightUpdate | AdminToMenuEntity::RightDelete)) > 0) {
            $crud->addField(new CrudField('operate', '操作', '', CrudField::ShowInListPage));
        }

        return $crud->execute();
    }

    /**
     * @inheritDoc
     */
    public function setForOp(Crud $crud, $extra)
    {
        $op = $crud->getOp();
        $op = empty($op) ? '' : trim($op);
        if ($op == 'listpage') {
            $this->setForGetListPage($crud);
        } elseif ($op == 'editpage') {
            $this->setForGetEditPage($crud, empty($extra['entity']) ? null : $extra['entity']);
        }
    }

    public function setForGetListPage(Crud $crud)
    {
        $crud->addFile(Crud::PageListPage, Crud::FileJsInline, \PhpYes\Apps::render()->getPage('admin/admin_menu_listpage.js'));
        $crud->setPageDisplayTarget(Crud::PageReadPage, 'layer', '800px', '500px');
        $crud->setPageDisplayTarget(Crud::PageEditPage, 'layer', '900px', '500px');

        // ---------- 列表页(listpage) searchbar
        $fieldName = 'pid';
        /** @var CrudField $crudField */
        $crudField = $crud->getField($fieldName);

        $optionMap = array('' => '请选择父菜单');
        $result = AdminMenuEntity::getAllMenuData();
        if ($result) {
            foreach ($result as $item) {
                $id = intval($item['id']);
                $level = empty($item['level']) ? 0 : intval($item['level']);
                $name = empty($item['name']) ? '' : trim($item['name']);
                $isInMenubar = empty($item['is_in_menubar']) ? 0 : intval($item['is_in_menubar']);
                $isInMenubar = empty($isInMenubar) ? '不在菜单栏' : '在菜单栏';
                $optionMap[$id] = "[{$id}]{$name}({$level}级)({$isInMenubar})";
            }
        }
        $crud->addLpSearchField(
            $fieldName,
            new LpSearchInputSelect(
                empty($crudField) ? '父菜单' : $crudField->getHName(),
                $optionMap
            )
        );

        $fieldName = 'name';
        $crudField = $crud->getField($fieldName);
        $crud->addLpSearchField(
            $fieldName,
            new LpSearchInputText(empty($crudField) ? '名称' : $crudField->getHName(), '请输入后台菜单名称')
        );

        $fieldName = 'path';
        $crudField = $crud->getField($fieldName);
        $crud->addLpSearchField(
            $fieldName,
            new LpSearchInputText(empty($crudField) ? '路径' : $crudField->getHName(), '请输入后台菜单路径')
        );

        $fieldName = 'isInMenubar';
        $crudField = $crud->getField($fieldName);
        $crud->addLpSearchField(
            $fieldName,
            new LpSearchInputSelect(
                empty($crudField) ? '是否在菜单栏中' : $crudField->getHName(),
                array(
                    -1 => '都可以',
                    0 => '否',
                    1 => '是'
                )
            )
        );
        // ----------

        // ---------- 列表页(listpage) 表格的字段设置
        $crud->getField('id')->setLpWidth('20px')->setLpIsSortable(true)->setLpClassName('dt-center');
        $crud->getField('pid')->setLpWidth('180px')->setLpIsSortable(true)->setLpRender(
            <<<'PIDRENDER'
function xx(data, type, row, meta) {
  return row.pname || '';
}
PIDRENDER
        );
        $crud->getField('level')->setLpWidth('20px')->setLpIsSortable(true)->setLpClassName('dt-center');
        $crud->getField('name')->setLpWidth('120px')->setLpIsSortable(false);
        $crud->getField('path')->setLpWidth('180px')->setLpIsSortable(false);
        $crud->getField('rights')->setLpWidth('100px')->setLpIsSortable(false)->setLpRender(
            <<<'RIGHTSRENDER'
function xx(data, type, row, meta) {
  return row.rightNames || '';
}
RIGHTSRENDER
        )->setLpClassName('dt-center');
        $crud->getField('isInMenubar')->setLpWidth('20px')->setLpIsSortable(true)->setLpRender(
            <<<'ISINMENUBARRENDER'
function xx(data, type, row, meta) {
  var isInMenubar = row.isInMenubar && parseInt(row.isInMenubar) || 0;
  return isInMenubar ? '是' : '否';
}
ISINMENUBARRENDER
        )->setLpClassName('dt-center');
        $crud->getField('priority')->setLpWidth('20px')->setLpIsSortable(true)->setLpRender(
            <<<'PRIORITYRENDER'
function xx(data, type, row, meta) {
  var priority = row.priority && parseInt(row.priority) || 0;
  return '<input type="number" value="' + priority + '" style="width: 3em;" min="0" max="255" />';
}
PRIORITYRENDER
        )->setLpClassName('dt-center');
        $crud->getField('icon')->setLpWidth('20px')->setLpIsSortable(false)->setLpRender(
            <<<'ICONRENDER'
function (data, type, row, meta) {
  var icon = row.icon && row.icon.trim() || null;
  if (!icon) {
    return '';
  }
  var iconColor = row.iconColor && row.iconColor.trim() || null;
  if (iconColor) {
    return '<i class="' + icon + '" style="color: ' + iconColor + ';"></i>';
  } else {
    return '<i class="' + icon + '"></i>';
  }
}
ICONRENDER
        )->setLpClassName('dt-center');
        $crud->getField('defaultQuery')->setLpWidth('180px')->setLpIsSortable(false);

        $crudField = $crud->getField('operate');
        if ($crudField) {
            $render = CrudField::getLpOperateRender($crud);
            $crudField->setLpWidth('100px')->setLpIsSortable(false)->setLpRender($render);
        }

        // ---------- 列表页(listpage) 表格的初始默认排序
        $crud->setLpOrder('id', 'desc');
    }

    /**
     * @param Crud $crud
     * @param AdminMenuEntity $entity
     */
    public function setForGetEditPage(Crud $crud, $entity)
    {
        $id = intval($entity->getId());
        $allMenu = AdminMenuEntity::getAllMenuData();
        if (empty($id)) {
            $validParentMenuList = $allMenu;
        } else {
            $excludeIds = array($id => true);
            $allMenuMap = array_column($allMenu, null, 'id');
            foreach ($allMenu as $menu) {
                $menuId = empty($menu['id']) ? 0 : intval($menu['id']);
                $pid = empty($menu['pid']) ? 0 : intval($menu['pid']);
                while ($pid) {
                    if ($pid === $id) {
                        $excludeIds[$menuId] = true;
                        break;
                    } else {
                        $pid = empty($allMenuMap[$pid]['pid']) ? 0 : intval($allMenuMap[$pid]['pid']);
                    }
                }
            }

            $validParentMenuList = array();
            foreach ($allMenu as $menu) {
                $menuId = empty($menu['id']) ? 0 : intval($menu['id']);
                if (empty($excludeIds[$menuId])) {
                    $validParentMenuList[] = $menu;
                }
            }
        }

        $optionMap = array();
        if ($validParentMenuList) {
            foreach ($validParentMenuList as $item) {
                $id = intval($item['id']);
                $name = empty($item['name']) ? '' : trim($item['name']);
                $level = empty($item['level']) ? 0 : intval($item['level']);
                $isInMenubar = empty($item['is_in_menubar']) ? 0 : intval($item['is_in_menubar']);
                $isInMenubar = empty($isInMenubar) ? '不在菜单栏' : '在菜单栏';
                $optionMap[$id] = "[{$id}]{$name}({$level}级)({$isInMenubar})";
            }
        }
        $crud->getField('pid')->setEpInputWidget(new InputSelect($optionMap, intval($entity->getPid())));
        $crud->getField('name')->setEpInputWidget(new InputText($entity->getName(), true, '请输入后台菜单名称'));
        $crud->getField('path')->setEpInputWidget(new InputText($entity->getPath(), false, '请输入后台菜单路径', null, 'style="width: 32em;"'));

        $origValue = [];
        $rights = intval($entity->getRights());
        if ($rights) {
            $rr = array(
                AdminToMenuEntity::RightRead,
                AdminToMenuEntity::RightCreate,
                AdminToMenuEntity::RightUpdate,
                AdminToMenuEntity::RightDelete
            );
            foreach ($rr as $r) {
                if (($rights & $r) > 0) {
                    $origValue[] = $r;
                }
            }
        }
        $crud->getField('rights')->setEpInputWidget(new InputCheckboxGroup(
            array(
                AdminToMenuEntity::RightRead => AdminToMenuEntity::$rightMap[AdminToMenuEntity::RightRead],
                AdminToMenuEntity::RightCreate => AdminToMenuEntity::$rightMap[AdminToMenuEntity::RightCreate],
                AdminToMenuEntity::RightUpdate => AdminToMenuEntity::$rightMap[AdminToMenuEntity::RightUpdate],
                AdminToMenuEntity::RightDelete => AdminToMenuEntity::$rightMap[AdminToMenuEntity::RightDelete]
            ),
            $origValue,
            true
        ));
        $crud->getField('isInMenubar')->setEpInputWidget(new InputCheckbox($entity->getIsInMenubar()));
        $crud->getField('icon')->setEpInputWidget(new InputText($entity->getIcon(), false, '请输入图标的class'));
        $crud->getField('iconColor')->setEpInputWidget(new InputText($entity->getIconColor(), false, '请输入图标的颜色'));
        $crud->getField('defaultQuery')->setEpInputWidget(new InputText($entity->getDefaultQuery(), false, '请输入url上的默认查询参数', null, 'style="width: 32em;"'));
    }

    /**
     * @inheritDoc
     */
    public function buildWhereForGetListData($params)
    {
        $where = array();
        $pid = empty($params['pid']) ? 0 : intval($params['pid']);
        if ($pid) {
            $where['pid'] = $pid;
        }

        $name = empty($params['name']) ? null : trim($params['name']);
        if ($name) {
            $where['name'] = array('like' => "%{$name}%");
        }

        $path = empty($params['path']) ? null : trim($params['path']);
        if ($path) {
            $where['path'] = array('like' => "%{$path}%");
        }

        if (isset($params['isInMenubar'])) {
            $isInMenubar = empty($params['isInMenubar']) ? 0 : intval($params['isInMenubar']);
            if ($isInMenubar >= 0) {
                if ($isInMenubar > 0) {
                    $where['is_in_menubar'] = 1;
                } else {
                    $where['is_in_menubar'] = 0;
                }
            }
        }

        return $where;
    }

    /**
     * @inheritDoc
     */
    public function buildOrderByForGetListData($fieldName, $direction)
    {
        $fieldName = empty($fieldName) ? null : trim($fieldName);
        if (empty($fieldName)) {
            return null;
        }
        $orderFieldMap = array(
            'id' => 'id',
            'pid' => 'pid',
            'level' => 'level',
            // 'name' => 'name',
            // 'path' => 'path',
            'isInMenubar' => 'is_in_menubar',
            'priority' => 'priority',
            // 'icon' => 'icon',
            // 'iconColor' => 'icon_color',
            // 'defaultQuery' => 'default_query',
        );
        $fieldName = empty($orderFieldMap[$fieldName]) ? null : $orderFieldMap[$fieldName];
        if (empty($fieldName)) {
            return null;
        }

        $direction = empty($direction) ? 0 : intval($direction);
        $direction = empty($direction) ? 'desc' : 'asc';
        return array($fieldName => $direction);
    }

    /**
     * @inheritDoc
     * @param AdminMenuEntity $entity
     */
    public function formatData(Crud $crud, BaseEntity $entity, $context = null)
    {
        $op = $crud->getOp();
        $op = empty($op) ? '' : trim($op);
        if ($op == 'readpage') {
            $data = $entity->format(array(
                'is_in_menubar' => 'isInMenubar',
                'priority' => false,
                'icon_color' => false,
                'default_query' => 'defaultQuery'
            ));
            $parent = $entity->getParentEntity();
            if (empty($parent)) {
                $data['pid'] = '';
            } else {
                $isInMenubar = intval($parent->getIsInMenubar());
                $isInMenubar = empty($isInMenubar) ? '不在菜单栏' : '在菜单栏';
                $data['pid'] = '[' . $parent->getId() . ']' . $parent->getName() . '(' . $parent->getLevel() . '级)(' . $isInMenubar . ')';
            }

            $data['rights'] = '[]';
            $rights = intval($entity->getRights());
            if ($rights) {
                $rightNames = [];
                $rr = array(
                    AdminToMenuEntity::RightRead,
                    AdminToMenuEntity::RightCreate,
                    AdminToMenuEntity::RightUpdate,
                    AdminToMenuEntity::RightDelete
                );
                foreach ($rr as $r) {
                    if (($rights & $r) > 0) {
                        $rightNames[] = AdminToMenuEntity::$rightMap[$r];
                    }
                }
                if ($rightNames) {
                    $data['rights'] = '[' . implode('，', $rightNames) . ']';
                }
            }

            $isInMenubar = $entity->getIsInMenubar();
            $data['isInMenubar'] = empty($isInMenubar) ? '否' : '是';

            $icon = $entity->getIcon();
            $icon = empty($icon) ? null : trim($icon);
            if ($icon) {
                $iconColor = $entity->getIconColor();
                $iconColor = empty($iconColor) ? null : trim($iconColor);
                if ($iconColor) {
                    $data['icon'] = '<i class="' . $icon . '" style="color: ' . $iconColor . ';"></i>';
                } else {
                    $data['icon'] = '<i class="' . $icon . '"></i>';
                }
            }
        } elseif ($op == 'editpage') {
            $data = $entity->formatSimple();
        } else {
            $data = $entity->formatSimple();
        }

        return $data;
    }

    /**
     * @inheritDoc
     */
    public function formatListData(Crud $crud, $data, $context = null)
    {
        if (empty($data)) {
            return null;
        }

        $op = $crud->getOp();
        $op = empty($op) ? '' : trim($op);
        $newDataList = array();
        if ($op == 'listdata') {
            $pidArr = array();
            foreach ($data as $item) {
                $pid = empty($item['pid']) ? 0 : intval($item['pid']);
                if ($pid) {
                    $pidArr[$pid] = 1;
                }
            }
            $map = array();
            if ($pidArr) {
                $pidArr = array_keys($pidArr);
                $result = AdminMenuEntity::getSingle()->select(array('id' => array('in' => $pidArr)));
                if ($result) {
                    foreach ($result as $item) {
                        $map[$item->getId()] = $item;
                    }
                }
            }
            $formatMap = array(
                'is_in_menubar' => 'isInMenubar',
                'icon_color' => 'iconColor',
                'default_query' => 'defaultQuery'
            );
            foreach ($data as $item) {
                $entity = new AdminMenuEntity($item);
                $newItem = $entity->format($formatMap);

                $pid = empty($newItem['pid']) ? 0 : intval($newItem['pid']);
                if ($pid && !empty($map[$pid])) {
                    /** @var AdminMenuEntity $parent */
                    $parent = $map[$pid];
                    $name = $parent->getName();
                    $level = $parent->getLevel();
                    $isInMenubar = intval($parent->getIsInMenubar());
                    $isInMenubar = empty($isInMenubar) ? '不在菜单栏' : '在菜单栏';
                    $newItem['pname'] = "[{$pid}]{$name}({$level}级)({$isInMenubar})";
                } else {
                    $newItem['pname'] = '';
                }

                $newItem['rightNames'] = '';
                $rights = empty($newItem['rights']) ? 0 : intval($newItem['rights']);
                if ($rights) {
                    $rightNames = [];
                    $rr = array(
                        AdminToMenuEntity::RightRead,
                        AdminToMenuEntity::RightCreate,
                        AdminToMenuEntity::RightUpdate,
                        AdminToMenuEntity::RightDelete
                    );
                    foreach ($rr as $r) {
                        if (($rights & $r) > 0) {
                            $rightNames[] = AdminToMenuEntity::$rightMap[$r];
                        }
                    }
                    if ($rightNames) {
                        $newItem['rightNames'] = implode('，', $rightNames);
                    }
                }

                $newDataList[] = $newItem;
            }
        } elseif ($op == 'export') {
            $formatMap = array(
                'is_in_menubar' => 'isInMenubar',
                'priority' => false,
                'icon' => false,
                'icon_color' => false,
                'default_query' => 'defaultQuery'
            );
            $allId2MenuMap = AdminMenuEntity::getAllId2MenuMap();
            foreach ($data as $item) {
                $entity = new AdminMenuEntity($item);
                $newItem = $entity->format($formatMap);

                $fieldName = 'pid';
                $pid = intval($entity->getPid());
                if (empty($pid)) {
                    $newItem[$fieldName] = '';
                } else {
                    $name = empty($allId2MenuMap[$pid]['name']) ? '' : trim($allId2MenuMap[$pid]['name']);
                    $level = empty($allId2MenuMap[$pid]['level']) ? 0 : intval($allId2MenuMap[$pid]['level']);
                    $isInMenubar = empty($allId2MenuMap[$pid]['is_in_menubar']) ? 0 : intval($allId2MenuMap[$pid]['is_in_menubar']);
                    $isInMenubar = empty($isInMenubar) ? '不在菜单栏' : '在菜单栏';
                    $newItem[$fieldName] = "[{$pid}]{$name}({$level}级)({$isInMenubar})";
                }

                $fieldName = 'rights';
                $rights = intval($entity->getRights());
                $newItem[$fieldName] = '';
                if ($rights) {
                    $rightNames = [];
                    $rr = array(
                        AdminToMenuEntity::RightRead,
                        AdminToMenuEntity::RightCreate,
                        AdminToMenuEntity::RightUpdate,
                        AdminToMenuEntity::RightDelete
                    );
                    foreach ($rr as $r) {
                        if (($rights & $r) > 0) {
                            $rightNames[] = AdminToMenuEntity::$rightMap[$r];
                        }
                    }
                    if ($rightNames) {
                        $newItem[$fieldName] = implode('，', $rightNames);
                    }
                }

                $fieldName = 'isInMenubar';
                $isInMenubar = intval($entity->getIsInMenubar());
                $newItem[$fieldName] = empty($isInMenubar) ? '否' : '是';

                $fieldName = 'defaultQuery';
                $defaultQuery = $entity->getDefaultQuery();
                $newItem[$fieldName] = empty($defaultQuery) ? '' : trim($defaultQuery);

                $newDataList[] = $newItem;
            }
        } else {
            foreach ($data as $item) {
                $entity = new AdminMenuEntity($item);
                $newItem = $entity->formatSimple();
                $newDataList[] = $newItem;
            }
        }
        return $newDataList;
    }

    /**
     * @inheritDoc
     * @param AdminMenuEntity $entity
     * @throws InvalidFieldValueException
     * @throws HttpException
     */
    public function createOrUpdate(Crud $crud, BaseEntity $entity, $data)
    {
        if (empty($data)) {
            return;
        }

        $op = $crud->getOp();
        $op = empty($op) ? '' : trim($op);
        if (empty($op)) {
            $fieldName = 'pid';
            $fieldHName = $crud->getField($fieldName)->getHName();
            $pid = empty($data[$fieldName]) ? 0 : intval($data[$fieldName]);
            if (empty($pid)) {
                throw new InvalidFieldValueException($fieldName, '请传递' . $fieldHName);
            }

            /** @var AdminMenuEntity $parent */
            $parent = AdminMenuEntity::getSingle()->selectById($pid);
            if (empty($parent)) {
                throw new InvalidFieldValueException($fieldName, '请传递有效的' . $fieldHName);
            }

            $entityId = intval($entity->getId());
            if ($entityId) { // 新增时没有id，所以还是应该判断一下
                if ($pid === $entityId) {
                    throw new InvalidFieldValueException($fieldName, '菜单的父菜单不能设置成菜单自己');
                }

                $p = $parent;
                while ($p) {
                    $pid = intval($p->getId());
                    if ($pid === $entityId) {
                        throw new InvalidFieldValueException($fieldName, '菜单的父菜单不能依赖菜单自己');
                    }
                    $p = $p->getParentEntity();
                }
            }
            $entity->setParentEntity($parent);

            $fieldName = 'name';
            $fieldHName = $crud->getField($fieldName)->getHName();
            $fieldVal = empty($data[$fieldName]) ? null : trim($data[$fieldName]);
            if (empty($fieldVal)) {
                throw new InvalidFieldValueException($fieldName, '请传递' . $fieldHName);
            }
            $entity->setName($fieldVal);

            $fieldName = 'path';
            // $fieldHName = $crud->getField($fieldName)->getHName();
            $fieldVal = empty($data[$fieldName]) ? null : trim($data[$fieldName]);
            $entity->setPath($fieldVal);

            $fieldName = 'rights';
            $fieldHName = $crud->getField($fieldName)->getHName();
            $fieldVal = empty($data[$fieldName]) ? null : $data[$fieldName];
            if (empty($fieldVal) || !is_array($fieldVal)) {
                throw new InvalidFieldValueException($fieldName, '请传递' . $fieldHName);
            }
            $rights = 0;
            foreach ($fieldVal as $r) {
                $r = empty($r) ? 0 : intval($r);
                if ($r && !empty(AdminToMenuEntity::$rightMap[$r])) {
                    $rights |= $r;
                }
            }
            if ($rights < 1) {
                throw new InvalidFieldValueException($fieldName, '请传递有效的' . $fieldHName);
            }
            $entity->setRights($rights);

            $fieldName = 'isInMenubar';
            // $fieldHName = $crud->getField($fieldName)->getHName();
            $fieldVal = empty($data[$fieldName]) ? 0 : intval($data[$fieldName]);
            $entity->setIsInMenubar($fieldVal);

            $fieldName = 'icon';
            // $fieldHName = $crud->getField($fieldName)->getHName();
            $fieldVal = empty($data[$fieldName]) ? null : trim($data[$fieldName]);
            $entity->setIcon($fieldVal);

            $fieldName = 'iconColor';
            // $fieldHName = $crud->getField($fieldName)->getHName();
            $fieldVal = empty($data[$fieldName]) ? null : trim($data[$fieldName]);
            $entity->setIconColor($fieldVal);

            $fieldName = 'defaultQuery';
            // $fieldHName = $crud->getField($fieldName)->getHName();
            $fieldVal = empty($data[$fieldName]) ? null : trim($data[$fieldName]);
            $entity->setDefaultQuery($fieldVal);
        } elseif ($op == 'updatePriority') {
            $priority = empty($data['priority']) ? 0 : intval($data['priority']);
            if ($priority < 0) {
                throw new HttpException('顺序不能小于0,顺序值的范围为:[0,255]');
            }
            if ($priority > 255) {
                throw new HttpException('顺序不能大于255,顺序值的范围为:[0,255]');
            }
            $entity->setPriority($priority);
        }
    }

    public function getListDataWithLoginAuth()
    {
        $param = \PhpYes\Apps::getReqQueryParams();

        $where = array();
        $pid = empty($param['pid']) ? 0 : intval($param['pid']);
        if ($pid) {
            $where['pid'] = $pid;
        }

        $name = empty($param['name']) ? null : trim($param['name']);
        if ($name) {
            $where['name'] = array('like' => "%{$name}%");
        }

        $path = empty($param['path']) ? null : trim($param['path']);
        if ($path) {
            $where['path'] = array('like' => "%{$path}%");
        }

        if (isset($param['isInMenubar'])) {
            $isInMenubar = empty($param['isInMenubar']) ? 0 : intval($param['isInMenubar']);
            if ($isInMenubar >= 0) {
                if ($isInMenubar > 0) {
                    $where['is_in_menubar'] = 1;
                } else {
                    $where['is_in_menubar'] = 0;
                }
            }
        }

        $orderBy = null;
        $orderFieldName = empty($param['_orderFieldName']) ? null : trim($param['_orderFieldName']);
        if ($orderFieldName) {
            $orderDirection = empty($param['_orderDirection']) ? 0 : intval($param['_orderDirection']);
            $orderBy = array($orderFieldName => empty($orderDirection) ? 'desc' : 'asc');
        }

        $entityTpl = AdminMenuEntity::getSingle();
        $qb = QueryBuilder::useDb($entityTpl->getConnName());

        $limit = empty($param['_limit']) ? 10 : intval($param['_limit']);
        $offset = empty($param['_offset']) ? 0 : intval($param['_offset']);
        $qbResult = $qb->select($entityTpl->getTable(), 'SQL_CALC_FOUND_ROWS *', $where, null, $orderBy, $limit, $offset);
        $dataList = $qbResult->getPdoStatement()->fetchAll(\PDO::FETCH_ASSOC);
        $result = $qbResult->getPdo()->query('SELECT FOUND_ROWS() AS cnt;')->fetchAll(\PDO::FETCH_ASSOC);
        $total = empty($result[0]['cnt']) ? 0 : intval($result[0]['cnt']);
        $result = $dataList;
        if (empty($result)) {
            return \PhpYes\Apps::render()->returnJson(array(
                'draw' => empty($param['_draw']) ? 0 : intval($param['_draw']),
                'total' => $total,
                'data' => array(),
            ));
        }

        $dataList = array();
        $class = get_class($entityTpl);
        foreach ($result as $item) {
            $entity = new $class($item);
            $dataList[] = $entity->formatSimple();
        }

        return \PhpYes\Apps::render()->returnJson(array(
            'draw' => empty($param['_draw']) ? 0 : intval($param['_draw']),
            'total' => $total,
            'data' => $dataList,
        ));
    }

}